package com.docker.core.handler;

import com.docker.core.constant.ConfigConstant;
import com.docker.sys.app.AppRedis;
import com.jfinal.core.JFinal;
import com.jfinal.handler.Handler;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.render.RenderManager;
import kit.docker.datetime.DateKit;
import kit.docker.security.MD5Kit;
import kit.docker.web.APIResCode;
import kit.docker.web.APIResponse;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Map;

public class APIHandler extends Handler {

    @Override
    public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
        if (!target.startsWith("api/") && !target.startsWith("/websocket")) {
            this.next.handle(target, request, response, isHandled);
            return;
        }
        if (target.startsWith("api/") && !"websocket".equals(request.getHeader("Upgrade"))) {
            httpHandle(target, request, response, isHandled);
        }
        if (target.startsWith("/websocket") && "websocket".equals(request.getHeader("Upgrade"))) {
            websocketHandle(target, request, response, isHandled);
        }
    }

    private void websocketHandle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
        //连接校验
        Map<String, String[]> paraMap = request.getParameterMap();
        //参数校验
        if (!StrKit.notNull(paraMap.get("connect_key"), paraMap.get("timestamp"), paraMap.get("sign"))) {
            System.out.println("请求参数校验失败：" + target);
            next.handle(target, request, response, isHandled);
            return;
        }

        //需要校验的参数
        String appId = paraMap.get("app_id")[0];
        String connectKey = paraMap.get("connect_key")[0];
        String timestamp = paraMap.get("timestamp")[0];
        String sign = paraMap.get("sign")[0];

        //完整性校验
        if (StrKit.isBlank(appId) || StrKit.isBlank(connectKey) || StrKit.isBlank(timestamp) || StrKit.isBlank(sign)) {
            System.out.println("请求参数校验失败：" + target);
            next.handle(target, request, response, isHandled);
            return;
        }

        //时间戳校验
        long defferTime = DateKit.getNowTimestamp() - Long.valueOf(timestamp);
        if (defferTime > PropKit.getLong(ConfigConstant.WEBSOCKET_DEFFER_TIME, 120L)) {
            System.out.println("时间戳认证失败：" + target);
            next.handle(target, request, response, isHandled);
            return;
        }

        //连接应用授权校验
        AppRedis.getApp(appId);

        //连接签名校验
        String paramStr = "app_id=" + appId + "connect_key=" + connectKey + "timestamp=" + timestamp;
        if (!sign.equals(MD5Kit.encodeMD5Hex(paramStr))) {
            System.out.println("安全协议验证失败：" + target);
            next.handle(target, request, response, isHandled);
            return;
        }

        //连接校验，不允许同一个连接键重复连接[暂行办法]
//        WebsocketPool socketPool = WebsocketPool.getSocketPool(appId);
//        if (StrKit.notNull(socketPool)) {
//            logger.error("websocket连接已存在，app_id=" + appId);
//            next.handle(target, request, response, isHandled);
//        }

    }

    private void httpHandle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
        if (target.equals(JFinal.me().getAction(target, new String[1]).getActionKey())) {
            next.handle(target, request, response, isHandled);
        } else {
            isHandled[0] = true;
            try {
                request.setCharacterEncoding("UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            RenderManager.me().getRenderFactory().getJsonRender(APIResponse.failStatus(APIResCode.RESOURCE_NOT_FOUND)).setContext(request, response).render();
        }
    }

}
